<?php
/**
 * RedXenon Framework
 * 
 * LICENSE
 * 
 * This source file is subject to the New BSD license that is bundled
 * with this package in the file LICENSE.txt
 * A copy of this license can be found in the world-wide-web at this URL:
 * http://www.redxenon.com/license/new-bsd-license.txt
 */

/** Date library require */
require_once(dirname(dirname(__FILE__))."/Date/RXDate.php");

/**
 * RedXenon File (RXFile.php)
 * Class that defines information regarding a File Object
 * 
 * @category RedXenon
 * @package RedXenon_File
 * @copyright Copyright (c) 2011 Red Xenon (http://www.redxenon.com)
 * @version $Id: RXFile.php 1.0 2011-04-25 $ 
 */
class RXFile {
	
	/**
	 * Path to the file
	 * @var String
	 */
	private $path;
	
	/**
	 * File extension
	 * @var String
	 */
	private $extension;
	
	/**
	 * File base name (with extension)
	 * @var String
	 */
	private $baseName;
	
	/**
	 * File name (without extension)
	 * @var String
	 */
	private $name;
	
	/**
	 * Parent directory
	 * @var String
	 */
	private $parentDirectory;
	
	/**
	 * File size
	 * @var Integer
	 */
	private $size;
	
	/**
	 * Last access time to the File
	 * @var RXDate
	 */
	private $lastAccessTime;
	
	/**
	 * Last modification time to the File
	 * @var RXDate
	 */
	private $lastModificationTime;
	
	/**
	 * File permissions
	 * @var String
	 */
	private $permissions;
	
	/**
	 * Username that owns the File
	 * @var String
	 */
	private $owner;
	
	/**
	 * Group name that owns the File
	 * @var String
	 */
	private $group;
	
	/**
	 * Constructor of the File Object
	 * @param String Path to the File
	 */
	public function __construct($path){
		if(file_exists($path)){
			if(is_file($path)){
				$this->path = $path;
				$this->parentDirectory = dirname($path);
				$this->extension = str_replace(".", "", strrchr(basename($path), "."));
				$this->baseName = basename($path);
				$this->name = basename($path, ".".$this->extension);
				$this->size = filesize($path);
				$this->lastAccessTime = new RXDate();
				$this->lastAccessTime->setUnixTime(fileatime($path));
				$this->lastModificationTime = new RXDate();
				$this->lastModificationTime->setUnixTime(filemtime($path));
				$this->permissions = self::processPermissions(fileperms($path));
				$this->owner = fileowner($path);
				$this->group = filegroup($path);				
			}else{
				throw new Exception("The path \"".$path."\" is not belong to a file" . PHP_EOL);
			}
		}else{
			$this->path = $path;
			$this->parentDirectory = dirname($path);
			$this->extension = str_replace(".", "", strrchr(basename($path), "."));
			$this->baseName = basename($path);
			$this->name = basename($path, ".".$this->extension);
			$this->size = 0;
			$this->lastAccessTime = new RXDate();
			$this->lastAccessTime->now();
			$this->lastModificationTime = new RXDate();
			$this->lastModificationTime->now();
			$this->permissions = NULL;
			$this->owner = NULL;
			$this->group = NULL;	
		}
	}

	/**
	 * Updates the File object information
	 */
	public function update(){		
		$this->parentDirectory = dirname($this->path);
		$this->extension = str_replace(".", "", strrchr(basename($this->path), "."));
		$this->baseName = basename($this->path);
		$this->name = basename($this->path, ".".$this->extension);
		$this->size = filesize($this->path);
		$this->lastAccessTime->setUnixTime(fileatime($this->path));
		$this->lastModificationTime->setUnixTime(filemtime($this->path));
		$this->permissions = self::processPermissions(fileperms($this->path));
		$this->owner = fileowner($this->path);
		$this->group = filegroup($this->path);				
	}

	/**
	 * @return String Path to the File
	 */
	public function getPath() {
		return $this->path;
	}

	/**
	 * @return String Extension of the File
	 */
	public function getExtension() {
		return $this->extension;
	}

	/**
	 * @return String Base name of the File (with extension)
	 */
	public function getBaseName() {
		return $this->baseName;
	}

	/**
	 * @return String Name of the file (without extension)
	 */
	public function getName() {
		return $this->name;
	}

	/**
	 * @return String Path to the Parent Directory
	 */
	public function getParentDirectory() {
		return $this->parentDirectory;
	}

	/**
	 * @return Integer File Size
	 */
	public function getSize() {
		return $this->size;
	}

	/**
	 * @return RXDate Last Access Time
	 */
	public function getLastAccessTime() {
		return $this->lastAccessTime;
	}

	/**
	 * @return RXDate Last Modification Time
	 */
	public function getLastModificationTime() {
		return $this->lastModificationTime;
	}

	/**
	 * @return String File Permissions
	 */
	public function getPermissions() {
		return $this->permissions;
	}

	/**
	 * @return String Username that owns the File
	 */
	public function getOwner() {
		return $this->owner;
	}

	/**
	 * @return String Group name that owns the File
	 */
	public function getGroup() {
		return $this->group;
	}

	/**
	 * @param String Path to the directory
	 */
	public function setPath($path) {
		$this->path = $path;
	}
	
	/**
	 * Avoids to use numeric permissions codes and translate them to a string
	 * Code Contained in php.net manual
	 * @param Integer $permissions
	 */
	public function processPermissions($permissions){
		if (($permissions & 0xC000) == 0xC000) {
			// Socket
			$perm = 's';
		} elseif (($permissions & 0xA000) == 0xA000) {
			// Symb Link
			$perm = 'l';
		} elseif (($permissions & 0x8000) == 0x8000) {
			// Regular
			$perm = '-';
		} elseif (($permissions & 0x6000) == 0x6000) {
			// Special Block
			$perm = 'b';
		} elseif (($permissions & 0x4000) == 0x4000) {
			// Direcectory
			$perm = 'd';
		} elseif (($permissions & 0x2000) == 0x2000) {
			// Special Character
			$perm = 'c';
		} elseif (($permissions & 0x1000) == 0x1000) {
			// FIFO Pipeline
			$perm = 'p';
		} else {
			// Unknown
			$perm = 'u';
		}
		
		// Owner Permissions
		$perm .= (($permissions & 0x0100) ? 'r' : '-');
		$perm .= (($permissions & 0x0080) ? 'w' : '-');
		$perm .= (($permissions & 0x0040) ? (($permissions & 0x0800) ? 's' : 'x') : (($permissions & 0x0800) ? 'S' : '-'));
		
		// Group Permissions
		$perm .= (($permissions & 0x0020) ? 'r' : '-');
		$perm .= (($permissions & 0x0010) ? 'w' : '-');
		$perm .= (($permissions & 0x0008) ? (($permissions & 0x0400) ? 's' : 'x') : (($permissions & 0x0400) ? 'S' : '-'));
		
		// Others Permissions
		$perm .= (($permissions & 0x0004) ? 'r' : '-');
		$perm .= (($permissions & 0x0002) ? 'w' : '-');
		$perm .= (($permissions & 0x0001) ? (($permissions & 0x0200) ? 't' : 'x') : (($permissions & 0x0200) ? 'T' : '-'));
		
		return $perm;
	}
	
	public function __toString(){
		return "	File Path:\t".$this->path."\n
						Basename:\t".$this->baseName."\n						
						Parent Dir:\t".$this->parentDirectory."\n
						Name:\t".$this->name."\n
						Extension:\t".$this->extension."\n
						File Size:\t".$this->size." Bytes\n
						Owner:\t".$this->owner."\n
						Group:\t".$this->group."\n
						Permissions:\t".$this->permissions."\n
						Last Access Time:\t".$this->lastAccessTime->getDate()."\n
						Last Modification Time:\t".$this->lastModificationTime->getDate()."\n";
	}
}

?>